<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import { marked } from 'marked';

const messages = ref([]);
const inputMessage = ref('');
const isLoading = ref(false);
const eventSource = ref(null);
const sessionId = ref(''); // 存储会话ID

// 生成UUID v4
const generateUUID = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
};

let lastKeyPressTime = 0;

const handleKeyDown = (event) => {
  if (event.key === 'Enter') {
    const now = Date.now();
    if (now - lastKeyPressTime < 500 && inputMessage.value.trim()) {
      sendMessage();
    }
    lastKeyPressTime = now;
  }
};

const sendMessage = () => {
  if (!inputMessage.value.trim()) return;
  
  // 添加用户消息到聊天记录
  const userMessage = {
    id: Date.now(),
    content: inputMessage.value,
    isUser: true
  };
  messages.value.push(userMessage);
  
  // 创建AI回复的占位消息
  const aiMessage = {
    id: Date.now() + 1,
    content: '',
    isUser: false
  };
  messages.value.push(aiMessage);

  scrollToBottom();
  
  // 清空输入框并设置加载状态
  const query = inputMessage.value;
  inputMessage.value = '';
  isLoading.value = true;
  
  // 关闭之前的连接（如果有）
  if (eventSource.value) {
    eventSource.value.close();
  }
  
  // 创建新的EventSource连接，传递会话ID
  const url = `/api/ai/chat/stream?query=${encodeURIComponent(query)}${sessionId.value ? `&sessionId=${sessionId.value}` : ''}`;
  eventSource.value = new EventSource(url);
  
  // 处理消息事件
  eventSource.value.onmessage = (event) => {
    console.log("收到消息:|" + event.data.substring(1) + "|");
    // 使用响应式方式更新消息内容，确保Vue能够检测到变化
    const lastIndex = messages.value.length - 1;
    if (lastIndex >= 0 && !messages.value[lastIndex].isUser) {
      // 创建新对象以确保响应式更新
      const updatedMessage = { ...messages.value[lastIndex] };
      updatedMessage.content += event.data.substring(1);
      messages.value[lastIndex] = updatedMessage;
      
      // 使用Vue的nextTick确保DOM更新后再滚动
      nextTick(() => {
        scrollToBottom();
      });
    }
  };
  
  // 处理连接建立事件
  eventSource.value.onopen = () => {
    console.log('连接已建立');
  };

  // 处理错误事件
  eventSource.value.onerror = (error) => {
    console.error('EventSource 错误:', error);
    isLoading.value = false;
    eventSource.value.close();
    eventSource.value = null;
    
    // 如果AI消息为空，添加错误提示
    if (!aiMessage.content) {
      aiMessage.content = '连接错误，请稍后重试。';
    }
  };
  
  // 处理连接关闭事件
  eventSource.value.addEventListener('done', () => {
    isLoading.value = false;
    eventSource.value.close();
    eventSource.value = null;
  });
};

const scrollToBottom = () => {
  // 减少延迟时间，使滚动更及时响应
  setTimeout(() => {
    const chatContainer = document.querySelector('.chat-messages');
    if (chatContainer) {
      chatContainer.scrollTop = chatContainer.scrollHeight;
    }
  }, 10);
};

// 清除对话历史并开始新会话
const clearChat = () => {
  // 如果有会话ID，调用后端接口清除服务器端会话
  if (sessionId.value) {
    fetch(`/api/ai/chat/session/${sessionId.value}`, {
      method: 'DELETE'
    }).then(() => {
      console.log('服务器端会话已清除');
    }).catch(error => {
      console.error('清除服务器端会话失败:', error);
    });
  }
  
  // 清除消息历史
  messages.value = [];
  // 生成新的会话ID
  const newSessionId = generateUUID();
  console.log('生成新会话ID:', newSessionId);
  sessionId.value = newSessionId;
  localStorage.setItem('chatSessionId', newSessionId);
  // 如果有活动连接，关闭它
  if (eventSource.value) {
    eventSource.value.close();
    eventSource.value = null;
  }
  isLoading.value = false;
};

// 组件卸载时关闭连接
onUnmounted(() => {
  if (eventSource.value) {
    eventSource.value.close();
    eventSource.value = null;
  }
});

// 导出聊天记录为图片
const exportToImage = async () => {
  const messagesContainer = document.querySelector('.chat-messages');
  if (!messagesContainer) {
    alert('未找到聊天消息容器');
    return;
  }

  // 检查是否有消息
  if (messages.value.length === 0) {
    alert('暂无聊天记录可导出');
    return;
  }

  const exportButton = document.querySelector('.export-button');
  const originalText = exportButton.textContent;
  const originalBgColor = exportButton.style.backgroundColor;
  
  try {
    // 显示加载状态
    exportButton.textContent = '正在导出...';
    exportButton.style.backgroundColor = '#ffc107';
    exportButton.disabled = true;
    
    // 动态导入html2canvas
    const html2canvas = (await import('html2canvas')).default;
    
    // 为了确保导出时显示完整内容，临时调整容器样式
    const originalScrollTop = messagesContainer.scrollTop;
    const originalOverflow = messagesContainer.style.overflow;
    const originalHeight = messagesContainer.style.height;
    const originalMaxHeight = messagesContainer.style.maxHeight;
    
    // 临时设置为可见所有内容
    messagesContainer.style.overflow = 'visible';
    messagesContainer.style.height = 'auto';
    messagesContainer.style.maxHeight = 'none';
    messagesContainer.scrollTop = 0;
    
    // 等待DOM更新
    await nextTick();
    await new Promise(resolve => setTimeout(resolve, 200));
    
    // 使用html2canvas截图
    const canvas = await html2canvas(messagesContainer, {
      backgroundColor: '#1a1a1a',
      scale: 2,
      useCORS: true,
      allowTaint: true,
      logging: false,
      
      // 在克隆时确保样式正确
      onclone: (clonedDoc) => {
        const clonedContainer = clonedDoc.querySelector('.chat-messages');
        if (clonedContainer) {
          clonedContainer.style.overflow = 'visible';
          clonedContainer.style.height = 'auto';
          clonedContainer.style.maxHeight = 'none';
        }
        
        // 注入样式确保渲染效果
        const style = clonedDoc.createElement('style');
        style.textContent = `
          .chat-messages {
            background-color: #1a1a1a !important;
            padding: 1rem !important;
          }
          .message-content {
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3),
                        0 4px 16px rgba(0, 0, 0, 0.2),
                        0 2px 8px rgba(0, 0, 0, 0.1),
                        inset 0 1px 0 rgba(255, 255, 255, 0.1) !important;
            backdrop-filter: blur(8px) !important;
          }
          .user-message .message-content {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
            border: 1px solid rgba(102, 126, 234, 0.3) !important;
          }
          .ai-message .message-content {
            background: linear-gradient(135deg, #1e293b 0%, #334155 50%, #475569 100%) !important;
            color: #ffffff !important;
            border: 1px solid rgba(71, 85, 105, 0.3) !important;
          }
          .user-message .message-header {
            background: linear-gradient(135deg, #5b6bc0 0%, #3f51b5 100%) !important;
            color: #ffffff !important;
          }
          .ai-message .message-header {
            background: linear-gradient(135deg, #1a252f 0%, #2d3748 100%) !important;
            color: #e2e8f0 !important;
          }
          pre {
            background: linear-gradient(135deg, #1e293b, #334155) !important;
            border: 1px solid #475569 !important;
            color: #e2e8f0 !important;
          }
          pre:before {
            content: 'SQL' !important;
            position: absolute !important;
            top: 0.5rem !important;
            right: 0.8rem !important;
            background: linear-gradient(135deg, #3b82f6, #1d4ed8) !important;
            color: white !important;
            padding: 0.2rem 0.6rem !important;
            border-radius: 4px !important;
            font-size: 0.7rem !important;
            font-weight: bold !important;
          }
        `;
        clonedDoc.head.appendChild(style);
      }
    });
    
    // 恢复原始样式
    messagesContainer.style.overflow = originalOverflow;
    messagesContainer.style.height = originalHeight;
    messagesContainer.style.maxHeight = originalMaxHeight;
    messagesContainer.scrollTop = originalScrollTop;
    
    // 创建下载链接
    const link = document.createElement('a');
    const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-');
    link.download = `btm-ai-chat-export-${timestamp}.png`;
    link.href = canvas.toDataURL('image/png', 1.0);
    
    // 触发下载
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    
    // 显示成功状态
    exportButton.textContent = '导出成功!';
    exportButton.style.backgroundColor = '#28a745';
    
  } catch (error) {
    console.error('导出图片失败:', error);
    
    // 显示详细错误信息
    let errorMessage = '导出图片失败，请稍后重试';
    if (error.message.includes('html2canvas')) {
      errorMessage = '导出功能加载失败，请检查网络连接后重试';
    } else if (error.message.includes('Canvas')) {
      errorMessage = '图片生成失败，可能是内容太长，请尝试清理部分历史记录后重试';
    }
    
    alert(errorMessage);
    
    // 显示失败状态
    exportButton.textContent = '导出失败';
    exportButton.style.backgroundColor = '#dc3545';
  } finally {
    // 恢复按钮状态
    setTimeout(() => {
      exportButton.textContent = originalText;
      exportButton.style.backgroundColor = originalBgColor;
      exportButton.disabled = false;
    }, 2000);
  }
};


// 组件挂载时滚动到底部并生成新的会话ID
onMounted(() => {
  scrollToBottom();
  
  // 生成新的会话ID
  const newSessionId = generateUUID();
  console.log('生成新会话ID:', newSessionId);
  sessionId.value = newSessionId;
  localStorage.setItem('chatSessionId', newSessionId);
});
</script>

<template>
  <div class="chat-container">
    <div class="chat-header">
      <h2>AI SQL查询助手工具</h2>
      <div class="header-buttons">
        <button @click="exportToImage" class="export-button" title="导出聊天记录为图片">
          <span>导出图片</span>
        </button>
        <button @click="clearChat" class="clear-button" title="清除对话历史">
          <span>新对话</span>
        </button>
      </div>
    </div>
    
    <div class="chat-messages" ref="chatContainer">
      <div v-if="messages.length === 0" class="empty-state">
        <p>开始与AI助手对话吧</p>
      </div>
      
      <div 
        v-for="message in messages" 
        :key="message.id" 
        :class="['message', message.isUser ? 'user-message' : 'ai-message']"
      >
        <div class="message-content">
          <div class="message-header">
            <span>{{ message.isUser ? '你' : 'AI' }}</span>
          </div>
          <div class="message-body">
            <div v-html="message.isUser ? message.content : marked(message.content)"></div>
          </div>
        </div>
      </div>
      
      <div v-if="isLoading" class="loading-indicator">
        <span></span>
        <span></span>
        <span></span>
      </div>
    </div>
    
    <div class="chat-input">
      <input 
        type="text" 
        v-model="inputMessage" 
        placeholder="输入消息..."
        :disabled="isLoading"
        @keydown.enter="handleKeyDown"
      />
      <button @click="sendMessage" :disabled="isLoading || !inputMessage.trim()">
        发送
      </button>
    </div>
  </div>
</template>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: 0;
  border-radius: 0;
  overflow: hidden;
  background-color: #1a1a1a;
  box-shadow: none;
  box-sizing: border-box;
}

.chat-header {
  padding: 1rem;
  background-color: #2c2c2c;
  border-bottom: 1px solid #3a3a3a;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.chat-header h2 {
  margin: 0;
  font-size: 1.5rem;
  color: #fff;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #888;
  font-style: italic;
}

.message {
  display: flex;
  margin-bottom: 1rem;
}

.user-message {
  justify-content: flex-end;
}

.ai-message {
  justify-content: flex-start;
}

.message-content {
  max-width: 80%;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 
    0 8px 32px rgba(0, 0, 0, 0.3),
    0 4px 16px rgba(0, 0, 0, 0.2),
    0 2px 8px rgba(0, 0, 0, 0.1),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
  transition: all 0.3s ease;
}

.message-content:hover {
  transform: translateY(-2px);
  box-shadow: 
    0 12px 40px rgba(0, 0, 0, 0.4),
    0 6px 20px rgba(0, 0, 0, 0.3),
    0 3px 12px rgba(0, 0, 0, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.15);
}

.user-message .message-content {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: 1px solid rgba(102, 126, 234, 0.3);
}

.ai-message .message-content {
  background: linear-gradient(135deg, #1e293b 0%, #334155 50%, #475569 100%);
  color: #ffffff;
  border: 1px solid rgba(71, 85, 105, 0.3);
}

.message-header {
  padding: 0.75rem 1.25rem;
  font-size: 0.85rem;
  font-weight: 600;
  position: relative;
  overflow: hidden;
}

.message-header::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
  transform: translateX(-100%);
  transition: transform 0.6s ease;
}

.message-content:hover .message-header::before {
  transform: translateX(100%);
}

.user-message .message-header {
  background: linear-gradient(135deg, #5b6bc0 0%, #3f51b5 100%);
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.ai-message .message-header {
  background: linear-gradient(135deg, #1a252f 0%, #2d3748 100%);
  color: #e2e8f0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

.message-body {
  padding: 1rem 1.25rem;
  position: relative;
}

.message-body {
  text-align: left;
}

.message-body div {
  margin: 0;
  white-space: pre-wrap;
}

.message-body :deep(*) {
  white-space: pre-wrap;
}

/* Markdown样式优化 */
.message-body :deep(p) {
  margin: 0.5rem 0;
  white-space: pre-wrap;
  line-height: 1.6;
}

/* SQL代码块专项优化 */
.message-body :deep(pre) {
  background: linear-gradient(135deg, #1e293b, #334155);
  border: 1px solid #475569;
  border-radius: 8px;
  padding: 1rem;
  margin: 0.8rem 0;
  overflow-x: auto;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1);
  position: relative;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 0.9rem;
  line-height: 1.5;
  color: #e2e8f0;
}

.message-body :deep(pre):before {
  content: 'SQL';
  position: absolute;
  top: 0.5rem;
  right: 0.8rem;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: white;
  padding: 0.2rem 0.6rem;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  box-shadow: 0 2px 4px rgba(59, 130, 246, 0.3);
}

/* 代码块中的SQL语法高亮样式 */
.message-body :deep(pre code) {
  background: transparent !important;
  padding: 0 !important;
  border-radius: 0 !important;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}

/* 行内代码样式 */
.message-body :deep(code) {
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  background: linear-gradient(135deg, #4f46e5, #3730a3);
  color: #ffffff;
  padding: 0.3rem 0.6rem;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 500;
}

.message-body :deep(ul), .message-body :deep(ol) {
  padding-left: 1.5rem;
  margin: 0.5rem 0;
  line-height: 1.6;
}

.message-body :deep(li) {
  margin-bottom: 0.3rem;
}

.message-body :deep(blockquote) {
  border-left: 4px solid #646cff;
  background: linear-gradient(135deg, #2a3441, #34495e);
  padding: 1rem 1.2rem;
  margin: 0.8rem 0;
  color: #e2e8f0;
  border-radius: 0 8px 8px 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  position: relative;
}

.message-body :deep(blockquote):before {
  content: '"';
  position: absolute;
  top: -0.5rem;
  left: -0.2rem;
  font-size: 4rem;
  color: #646cff;
  opacity: 0.3;
  font-family: serif;
}

/* 表格样式优化 */
.message-body :deep(table) {
  width: 100%;
  border-collapse: collapse;
  margin: 1rem 0;
  background: linear-gradient(135deg, #1e293b, #334155);
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.message-body :deep(th),
.message-body :deep(td) {
  padding: 0.8rem 1rem;
  text-align: left;
  border-bottom: 1px solid #475569;
  color: #e2e8f0;
}

.message-body :deep(th) {
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: white;
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.85rem;
  letter-spacing: 0.5px;
}

.message-body :deep(tr):hover {
  background-color: rgba(100, 108, 255, 0.1);
}

/* 标题样式优化 */
.message-body :deep(h1),
.message-body :deep(h2),
.message-body :deep(h3),
.message-body :deep(h4),
.message-body :deep(h5),
.message-body :deep(h6) {
  color: #f1f5f9;
  margin: 1rem 0 0.5rem 0;
  font-weight: 600;
  line-height: 1.3;
}

.message-body :deep(h1) {
  font-size: 1.8rem;
  border-bottom: 2px solid #646cff;
  padding-bottom: 0.5rem;
}

.message-body :deep(h2) {
  font-size: 1.5rem;
  color: #646cff;
}

.message-body :deep(h3) {
  font-size: 1.3rem;
  color: #94a3b8;
}

/* 强调文本样式 */
.message-body :deep(strong) {
  color: #fbbf24;
  font-weight: 700;
}

.message-body :deep(em) {
  color: #a78bfa;
  font-style: italic;
}

.chat-input {
  display: flex;
  padding: 1rem;
  background-color: #2c2c2c;
  border-top: 1px solid #3a3a3a;
}

.chat-input input {
  flex: 1;
  padding: 0.8rem 1rem;
  border: none;
  border-radius: 4px;
  background-color: #3a3a3a;
  color: #fff;
  margin-right: 0.5rem;
}

.chat-input input:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(100, 108, 255, 0.5);
}

.chat-input button {
  padding: 0.8rem 1.5rem;
  background-color: #646cff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-weight: bold;
}

.chat-input button:hover:not(:disabled) {
  background-color: #535bf2;
}

.chat-input button:disabled {
  background-color: #4a4a4a;
  cursor: not-allowed;
  opacity: 0.7;
}

.loading-indicator {
  display: flex;
  justify-content: center;
  margin: 1rem 0;
}

.loading-indicator span {
  width: 8px;
  height: 8px;
  margin: 0 4px;
  border-radius: 50%;
  background-color: #646cff;
  animation: bounce 1.4s infinite ease-in-out both;
}

.loading-indicator span:nth-child(1) {
  animation-delay: -0.32s;
}

.loading-indicator span:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0);
  } 
  40% {
    transform: scale(1);
  }
}

.header-buttons {
  display: flex;
  gap: 0.5rem;
}

.clear-button,
.export-button {
  background-color: #4a4a4a;
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background-color 0.2s;
}

.clear-button:hover {
  background-color: #646cff;
}

.export-button {
  background-color: #28a745;
  transition: all 0.3s ease;
}

.export-button:hover:not(:disabled) {
  background-color: #218838;
  transform: translateY(-1px);
}

.export-button:disabled {
  opacity: 0.7;
  cursor: not-allowed;
  transform: none;
}
</style>